﻿#include "ui.h"
#include "string.h"


#define ICON_WIDTH  8 /* 图标宽度 */
#define ICON_HEIGHT 7  /* 图标高度 */


/* 波形数据 */
uint16_t oscillData[OSCILL_DATA_LEN] = { 0 };

/* 指示图标 */
static const uint8_t icon[ICON_HEIGHT][ICON_WIDTH] = {
    1, 1, 1, 1, 1, 0, 0, 0,
    1, 1, 1, 1, 1, 1, 0, 0,
    1, 1, 1, 1, 1, 1, 1, 0,
    1, 1, 1, 1, 1, 1, 1, 1,
    1, 1, 1, 1, 1, 1, 1, 0,
    1, 1, 1, 1, 1, 1, 0, 0,
    1, 1, 1, 1, 1, 0, 0, 0,
};


static uint16_t _Vol2Y(const Oscill_t *oscill, int16_t voltage);
static uint16_t _Indx2X(const Oscill_t *oscill, uint16_t index);


/**
 * @brief 绘制波形窗口
 * @param window 窗口结构体
 */
void UI_DrawOscilloWindow(const Oscill_t *window)
{
    /* 在临界区拷贝一份数据 */
    taskENTER_CRITICAL();
    Oscill_t tmp = *window;
    taskEXIT_CRITICAL();

    /* 设置边框颜色 */
    LCD_SetForeColor(tmp.parent.colorBorder);

    /* 绘制边框 */
    LCD_DrawRectangle(tmp.parent.x, tmp.parent.y,
        tmp.parent.x + tmp.parent.width, tmp.parent.y + tmp.parent.height
    );

    /* 设置网格颜色 */
    LCD_SetForeColor(tmp.colorGrid);

    /* 绘制网格横线 */
    for(int i = 1; i <= 7; i++)
    {
        LCD_DrawLine(tmp.parent.x, tmp.parent.y + i * tmp.sizeGrid,
            tmp.parent.x + tmp.parent.width, tmp.parent.y + i * tmp.sizeGrid
        );
    }

    /* 绘制网格竖线 */
    for(int i = 1; i <= 11; i++)
    {
        LCD_DrawLine(tmp.parent.x + i * tmp.sizeGrid, tmp.parent.y,
            tmp.parent.x + i * tmp.sizeGrid, tmp.parent.y + tmp.parent.height
        );
    }

    /* 恢复原来的前景色 */
    LCD_SetForeColor(FORECOLOR);

    /* 绘制垂直位置指示 */
    for(int i = 0; i < ICON_HEIGHT; i++)
    {
        uint16_t y = tmp.parent.y + tmp.vpi.value + i - ICON_HEIGHT / 2;
        for(int j = 0; j < ICON_WIDTH; j++)
            if(icon[i][j])
            {
                uint16_t x = tmp.parent.x - ICON_WIDTH - 1 + j;
                LCD_Fast_DrawPoint(x, y, tmp.vpi.color);
            }
    }

    /* 绘制触发电平指示 */
    for(int i = 0; i < ICON_HEIGHT; i++)
    {
        uint16_t y = tmp.parent.y + tmp.vpi.value + i - ICON_HEIGHT / 2;
        for(int j = ICON_WIDTH - 1; j >= 0; j--)
            if(icon[i][j])
            {
                uint16_t x = tmp.parent.x + tmp.parent.width + ICON_WIDTH - j;
                LCD_Fast_DrawPoint(x, y, tmp.vpi.color);
            }
    }

    // log("tick0: %d\n", xTaskGetTickCount());
    /* 绘制波形 */
    // LCD_Clear(BACK_COLOR);
    LCD_SetForeColor(YELLOW);
    for(int i = 0; i < OSCILL_DATA_LEN; i++)
    {
        uint16_t x1 = _Indx2X(&tmp, i);
        uint16_t x2 = _Indx2X(&tmp, i + 1);
        uint16_t y1 = _Vol2Y(&tmp, (int16_t)oscillData[i]);
        uint16_t y2 = _Vol2Y(&tmp, (int16_t)oscillData[i + 1]);

        LCD_Fill(x1, tmp.parent.y, x2, tmp.parent.y + tmp.parent.height, BACKCOLOR);
        LCD_DrawLine(x1, y1, x2, y2);
    }
    // log("tick1: %d\n", xTaskGetTickCount());
}

/**
 * @brief 绘制上边栏
 */
void UI_DrawUpperSildebar(const UpperSildebar_t *upperSildebar)
{
    /* 在临界区拷贝一份数据 */
    taskENTER_CRITICAL();
    UpperSildebar_t tmp = *upperSildebar;
    taskEXIT_CRITICAL();
    (void)tmp;
}

/**
 * @brief 绘制下边栏
 */
void UI_DrawLowerSildebar(const LowerSildebar_t *lowerSildebar)
{
    /* 在临界区拷贝一份数据 */
    taskENTER_CRITICAL();
    LowerSildebar_t tmp = *lowerSildebar;
    taskEXIT_CRITICAL();

    uint16_t x = 0, y = 0, width = 0, height = 0;

    /* 绘制verSensitivity(垂直灵敏度)文本视图 */
    x = tmp.parent.x + tmp.verSensitivity.x;
    y = tmp.parent.y + tmp.verSensitivity.y;
    width = tmp.verSensitivity.size / 2 * 4;
    height = tmp.verSensitivity.size;

    LCD_SetForeColor(tmp.verSensitivity.color); /* 设置前景色 */
    LCD_ShowString(x, y, width, height,
                   tmp.verSensitivity.size, (uint8_t *)tmp.verSensitivity.text);

    /* 绘制cplMode(耦合模式)文本视图 */
    x = tmp.parent.x + tmp.cplMode.x;
    y = tmp.parent.y + tmp.cplMode.y;
    width = tmp.cplMode.size / 2 * 3;
    height = tmp.cplMode.size;

    LCD_SetForeColor(tmp.cplMode.color); /* 设置前景色 */
    LCD_ShowString(x, y, width, height,
                   tmp.cplMode.size, (uint8_t *)tmp.cplMode.text);

    /* 绘制timeBase(时基)文本视图 */
    LCD_SetForeColor(tmp.parent.colorBorder);
    LCD_DrawRectangle(x - 2, y - 2,
                      x + width + 2, y + height + 2);

    /* 绘制trigMode(触发方式)文本视图 */

    /* 绘制trigEdege(触发边沿)文本视图 */

    /* 恢复默认前景色 */
    LCD_SetForeColor(FORECOLOR);
}


/*********************************** 私有函数 ***********************************/

/**
 * @brief 将电压值转换为对应波形点Y坐标
 * @param oscill 波形结构体
 * @param voltage 电压值
 * @return 波形点Y坐标
 */
static uint16_t _Vol2Y(const Oscill_t *oscill, int16_t voltage)
{
    int16_t ret = 0;

    ret = (int16_t)(voltage / ((float)oscill->sensiv / oscill->sizeGrid));
    ret = oscill->vpi.value - ret;

    if(ret >= oscill->parent.y + oscill->parent.height)
        ret = oscill->parent.y + oscill->parent.height - 3;
    else if(ret <= oscill->parent.y)
        ret = oscill->parent.y + 3;

    return ret;
}

/**
 * @brief 索引转换为x坐标
 * @param oscill 波形结构体
 * @param index 索引下标
 */
static uint16_t _Indx2X(const Oscill_t *oscill, uint16_t index)
{
    uint16_t ret = 0;

    ret = oscill->parent.x + index * 2;

    if(ret >= oscill->parent.x + oscill->parent.width)
        ret = oscill->parent.x + oscill->parent.width - 3;
    else if(ret <= oscill->parent.x)
        ret = oscill->parent.x + 3;

    return ret;
}
